package aos.system.modules.group;

import java.util.List;

import aos.ydksxt.util.GuidUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

import aos.framework.core.dao.SqlDao;
import aos.framework.core.typewrap.Dto;
import aos.framework.core.typewrap.Dtos;
import aos.framework.core.utils.AOSCons;
import aos.framework.core.utils.AOSJson;
import aos.framework.core.utils.AOSUtils;
import aos.framework.web.router.HttpModel;
import aos.system.common.id.IdService;
import aos.system.common.model.UserModel;
import aos.system.common.utils.SystemCons;
import aos.system.common.utils.SystemUtils;
import aos.system.dao.AosGroupDao;
import aos.system.dao.AosUserGroupDao;
import aos.system.dao.po.AosGroupPO;
import aos.system.dao.po.AosOrgPO;
import aos.system.dao.po.AosUserGroupPO;
import aos.system.modules.cache.CacheUserDataService;

/**
 * 群组管理
 * 
 * @author xiongchun
 *
 */
@Service
public class GroupService {
	
	@Autowired
	private AosGroupDao aosGroupDao;
	@Autowired
	private SqlDao sqlDao;
	@Autowired
	private IdService idService;	
	@Autowired
	private CacheUserDataService cacheUserDataService;
	@Autowired
	private AosUserGroupDao aosUserGroupDao;
	/**
	 * 群组管理页面初始化
	 * 
	 * @param httpModel
	 * @return
	 */
	public void init(HttpModel httpModel) {
		AosGroupPO aosGroupPO = aosGroupDao.selectOne(Dtos.newDto("parent_id", SystemCons.ROOTNODE_PARENT_ID));
		httpModel.setAttribute("rootPO", aosGroupPO);
		httpModel.setViewPath("system/group.jsp");
	}
	
	/**
	 * 获取群组导航树
	 * 
	 * @param httpModel
	 * @return
	 */
	public void getTreeData(HttpModel httpModel) {
		Dto inDto = httpModel.getInDto();
		inDto.setOrder("sort_no");
		inDto.put("is_del", SystemCons.IS.NO);
		List<AosGroupPO> aosGroupPOs = aosGroupDao.list(inDto);
		List<Dto> modelDtos = Lists.newArrayList();
		for (AosGroupPO aosGroupPO : aosGroupPOs) {
			modelDtos.add(aosGroupPO.toDto());
		}
		String treeJson = SystemUtils.toTreeModalAsyncLoad(modelDtos);
		httpModel.setOutMsg(treeJson);
	}
	

	/**
	 * 查询群组列表
	 * 
	 * @param httpModel
	 * @return
	 */
	public void listOrgs(HttpModel httpModel) {
		Dto qDto = httpModel.getInDto();
		qDto.put("is_del", SystemCons.IS.NO);
		List<Dto> groupDtos = sqlDao.list("Group.listGroupsPage", qDto);
		httpModel.setOutMsg(AOSJson.toGridJson(groupDtos, qDto.getPageTotal()));
	}
	/**
	 * 查询待选用户列表
	 * 
	 * @param httpModel
	 * @return
	 */
	public void listUsers(HttpModel httpModel) {
		Dto qDto = httpModel.getInDto();
		AosOrgPO aosOrgPO = httpModel.getUserModel().getAosOrgPO();
		if (AOSUtils.isEmpty(qDto.getString("org_id"))) {
			qDto.put("org_id", aosOrgPO.getId());
		}
		if (AOSUtils.isEmpty(qDto.getString("org_cascade_id"))) {
			qDto.put("org_cascade_id", aosOrgPO.getCascade_id());
		}
		qDto.put("is_del", SystemCons.IS.NO);
		qDto.put("cascade", qDto.getBoolean("cascade") ? 1 : 0);
		List<Dto> userDtos = sqlDao.list("Group.listUsersPage", qDto);

		httpModel.setOutMsg(AOSJson.toGridJson(userDtos, qDto.getPageTotal()));
	}

	/**
	 * 查询已选用户列表
	 * 
	 * @param httpModel
	 * @return
	 */
	public void listSelectedUsers(HttpModel httpModel) {
		Dto qDto = httpModel.getInDto();
		AosOrgPO aosOrgPO = httpModel.getUserModel().getAosOrgPO();
		if (AOSUtils.isEmpty(qDto.getString("org_id"))) {
			qDto.put("org_id", aosOrgPO.getId());
		}
		if (AOSUtils.isEmpty(qDto.getString("org_cascade_id"))) {
			qDto.put("org_cascade_id", aosOrgPO.getCascade_id());
		}
		qDto.put("is_del", SystemCons.IS.NO);
		List<Dto> userDtos = sqlDao.list("Group.listSelectedUsersPage", qDto);

		httpModel.setOutMsg(AOSJson.toGridJson(userDtos, qDto.getPageTotal()));
	}
	/**
	 * 保存角色用户关联关系
	 * 
	 * @param httpModel
	 */
	@Transactional
	public void saveGroupUserGrantInfo(HttpModel httpModel) {
		Dto inDto = httpModel.getInDto();
		String group_id = inDto.getString("group_id");
		String[] selectionIds = httpModel.getInDto().getRows();
		for (String id : selectionIds) {
			AosUserGroupPO aosUserGroupPO = new AosUserGroupPO();
			aosUserGroupPO.setId(GuidUtils.getRandomUUID());
			aosUserGroupPO.setGroup_id(group_id);
			aosUserGroupPO.setUser_id(id);
			aosUserGroupPO.setCreate_by(httpModel.getUserModel().getId());
			aosUserGroupPO.setCreate_time(AOSUtils.getDateTime());
			aosUserGroupDao.insert(aosUserGroupPO);
			cacheUserDataService.resetGrantInfoOfUser(id);
		}
		httpModel.setOutMsg("群组用户关联关系保存成功。");
	}

	/**
	 * 撤消角色用户关联关系
	 * 
	 * @param httpModel
	 */
	@Transactional
	public void deleteGroupUserGrantInfo(HttpModel httpModel) {
		String[] selectionIds = httpModel.getInDto().getRows();
		for (String id : selectionIds) {
			AosUserGroupPO aosUserGroupPO = aosUserGroupDao.selectByKey(String.valueOf(id));
			aosUserGroupDao.deleteByKey(String.valueOf(id));
			cacheUserDataService.resetGrantInfoOfUser(aosUserGroupPO.getUser_id());
		}
		httpModel.setOutMsg("撤消群组用户关联关系成功。");
	}

	/**
	 * 保存群组
	 * 
	 * @param httpModel
	 * @return
	 */
	@Transactional
	public void saveOrg(HttpModel httpModel) {
		UserModel userModel = httpModel.getUserModel();
		Dto inDto = httpModel.getInDto();
		AosGroupPO aosGroupPO = new AosGroupPO();
		aosGroupPO.copyProperties(inDto);
		aosGroupPO.setId(GuidUtils.getRandomUUID());
		
		// 生成语义ID
		AosGroupPO parentAosGroupPO = aosGroupDao.selectByKey(String.valueOf(aosGroupPO.getParent_id()));
		String max_cascade_id = (String)sqlDao.selectOne("Group.getMaxCascadeId", aosGroupPO.getParent_id());
		if (AOSUtils.isEmpty(max_cascade_id)) {
			String temp = "0";
			if (AOSUtils.isNotEmpty(parentAosGroupPO)) {
				temp = parentAosGroupPO.getCascade_id();
			}
			max_cascade_id = temp + ".000";
		}
		String cascade_id = SystemUtils.genCascadeTreeId(max_cascade_id, 999);
		aosGroupPO.setCascade_id(cascade_id);
		
		aosGroupPO.setIs_leaf(SystemCons.IS.YES);
		aosGroupPO.setCreate_by(userModel.getId());
		aosGroupPO.setCreate_time(AOSUtils.getDateTime());
		aosGroupPO.setIs_del(SystemCons.IS.NO);
		aosGroupDao.insert(aosGroupPO);
		
		
		//更新父节点的是否叶子节点字段
		AosGroupPO updatePO = new AosGroupPO();
		updatePO.setId(String.valueOf(aosGroupPO.getParent_id()));
		updatePO.setIs_leaf(SystemCons.IS.NO);
		aosGroupDao.updateByKey(updatePO);
		
		httpModel.setOutMsg("群组新增成功。");
	}
	
	/**
	 * 修改群组
	 * 
	 * @param httpModel
	 * @return
	 */
	@Transactional
	public void updateOrg(HttpModel httpModel) {
		Dto inDto = httpModel.getInDto();
		AosGroupPO aosGroupPO = new AosGroupPO();
		aosGroupPO.copyProperties(inDto);
		aosGroupDao.updateByKey(aosGroupPO);
		httpModel.setOutMsg("群组修改成功。");
	}
	
	/**
	 * 删除群组
	 * 
	 * @param httpModel
	 */
	@Transactional
	public void deleteOrg(HttpModel httpModel) {
		Dto outDto = Dtos.newOutDto();
		String[] selectionIds = httpModel.getInDto().getRows();
		AosGroupPO aosGroupPO = (AosGroupPO)sqlDao.selectOne("Group.checkRootNode", Dtos.newDto("ids", StringUtils.join(selectionIds, ",")));
		if (AOSUtils.isNotEmpty(aosGroupPO)) {
			outDto.setAppCode(AOSCons.ERROR);
			outDto.setAppMsg(AOSUtils.merge("操作失败，根节点[{0}]不能删除。", aosGroupPO.getName()));
		}else {
			for (String id : selectionIds) {
				AosGroupPO delPO = aosGroupDao.selectByKey(String.valueOf(id));
				if (AOSUtils.isEmpty(delPO)) {
					continue;
				}
				
				List<AosGroupPO> subDelList = aosGroupDao.like(Dtos.newDto("cascade_id", delPO.getCascade_id()));
				for (AosGroupPO subDelPO : subDelList) {
					//逻辑删除群组
					subDelPO.setIs_del(SystemCons.IS.YES);
					aosGroupDao.updateByKey(subDelPO);
					//逻辑删除群组下辖的用户
					sqlDao.update("Group.updateUserInfoByGroupId", subDelPO.getId());
				}
				
				//更需父节点的是否叶子节点属性
				Dto checkDto = Dtos.newDto("parent_id", delPO.getParent_id());
				checkDto.put("is_del", SystemCons.IS.NO);
				if (aosGroupDao.rows(checkDto) == 0) {
					AosGroupPO updatePO = new AosGroupPO();
					updatePO.setId(String.valueOf(delPO.getParent_id()));
					updatePO.setIs_auto_expand(SystemCons.IS.NO);
					updatePO.setIs_leaf(SystemCons.IS.YES);
					aosGroupDao.updateByKey(updatePO);
				}
				
			}
			outDto.setAppMsg("成功删除群组数据。");
		}
		httpModel.setOutMsg(AOSJson.toJson(outDto));
	}
	
}
